
/*
事件类型
touchstart	手指触摸动作开始
touchmove	手指触摸后移动
touchcancel	手指触摸动作被打断，如来电提醒，弹窗
touchend	手指触摸动作结束
tap	手指触摸后马上离开
longpress	手指触摸后，超过350ms再离开，如果指定了事件回调函数并触发了这个事件，tap事件将不被触发	1.5.0
longtap	手指触摸后，超过350ms再离开（推荐使用longpress事件代替）
*/
class UIEvent
{
    constructor(elem, event, callback)
    {
        if (!elem || !event || !callback) {
            console.warn('UIEvent invalid parameters');
            return;
        }
        this.elem = elem;
        this.event = event;
        this.callback = callback;

        //simple event
        if (event === 'touchstart'
            || event === 'touchmove'
            || event === 'touchcancel'
            || event === 'touchend') {
            elem.addEventListener(event, this.onEvent.bind(this));
        }
        else if (event === 'tap'
            || event === 'longpress'
            || event === 'longtap') {
            let handler = this.onEvent.bind(this);
            elem.addEventListener('touchstart', handler);
            elem.addEventListener('touchcancel', handler);
            elem.addEventListener('touchmove', handler);
            elem.addEventListener('touchend', handler);
        }
        else {
            console.warn("invalid event type '" + event + "'");
        }
    }

    onEvent(e) {

    }
}

export class TapEvent{
    constructor(elem, callback)
    {
        if (!elem || !callback) {
            console.warn("TapEvent, invalid create parameters");
            return;
        }

        this.elem = elem;
        this.callback = callback;
        this.canceled = false;
        this.touchStartTime = 0;

        let handler = this.onTouchEvent.bind(this);
        elem.addEventListener('touchstart', handler);
        elem.addEventListener('touchcancel', handler);
        elem.addEventListener('touchmove', handler);
        elem.addEventListener('touchend', handler);
    }

    onTouchEvent(e) {
        if (e.type === 'touchstart') {
            e.preventDefault();
            if (e.targetTouches.length > 0) {
                this.canceled = false;
                this.touchStartTime = Date.now();
            }
        }
        else if (e.type === 'touchcancel') {
            this.canceled = true;
        }
        else if (e.type === 'touchmove') {
            this.canceled = true;
        }
        else if (e.type === 'touchend') {
            let interval = Date.now() - this.touchStartTime;
            this.touchStartTime = 0;
            if (interval < 100 && !this.canceled) {
                this.callback(e);
            }
        }
    }
}



export class UIEventHandler
{
    constructor(page, elem, eventName, callback, stopPropagation) {
        this.page = page;
        this.elem = elem;
        this.callback = callback;   //exp, callback function or function name
        this.eventName = eventName;
        this.stopPropagation = stopPropagation === undefined ? false : stopPropagation;

        this.init();
    }

    init() {

        if (this.eventName === 'click') {
            this.elem.addEventListener(this.eventName, (e) => {
                this.onEvent(e);
            });
        }
        else if (this.eventName === 'tap') {
            //todo:
            this.elem.addEventListener('click', (e) => {
                this.onEvent(e);
            });
        }
    }

    onEvent(e) {

        if (this.stopPropagation) {
            e.stopPropagation();
        }

        let eventData = this.translateDOMEvent(e);
        let param = {
            host: this,
            name: this.eventName,
            data: eventData,
            callback: this.callback
        };

        if (this.page) {
            this.page.onUIEvent(param);
        }
    }

    translateDOMEvent(e) {
        const props = ['type', 'x', 'y', 'screenX', 'screenY', 'bubbles'];
        let data = {};
        props.forEach((key) => {
            if (key in e) {
                data[key] = e[key];
            }
        });
        return data;
    }

    detach() {
        this.page.removeUIEventHandler(this);
        this.page = null;
    }
}